package au.edu.swin.MelbourneMap;


import java.awt.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.filechooser.FileFilter;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.KeyEvent;

 
/**
 * Java Swing GUI implementation of View class using Model View Controller architecture.
 *
 * @author  Alexis Wellavize (s/n: 6033482)<br/>
 *           Dotan Tamir (s/n: 6532969)
 * @since   v1, created:  17/09/2012
 * @version v2, modified:  22/09/2012
 *
 */
 
public class View extends JFrame
{
    private Container contentPane = getContentPane();
    private JPanel panningPanel = new JPanel();
    private JPanel zoomingPanel = new JPanel();
    private JPanel buttonsPanel = new JPanel();
    private JPanel statusPanel = new JPanel();
    private JPanel innerPanel = new JPanel();
    private MapPanel mappingPanel;
    private JButton upPanning = new JButton("^");
    private JButton leftPanning = new JButton( "<");
    private JButton rightPanning = new JButton(">");
    private JButton downPanning = new JButton("v");
    private JButton zoomInButton = new JButton( "+");
    private JButton zoomOutButton = new JButton("-");
    private JButton resetButton = new JButton("reset");
    private JLabel statusLabel = new JLabel("X,Y: ");
    private JMenuBar menuBar = new JMenuBar();
    private JMenuItem openAction;
    private JMenuItem saveAction;    
    private JMenuItem exitAction;
    private JMenuItem cutAction;
    private JMenuItem copyAction;
    private JMenuItem pasteAction;
    private JMenuItem aboutAction;
    private JMenuItem zoomPanelAction;
    private JCheckBoxMenuItem labelsAction;
    private JDesktopPane desktop; 
    private JComboBox suburbs; 
    private JMenu saveAsAction;
    private JMenuItem railData;
    private JMenuItem roadData;
    private JMenuItem regionData;
    private Model model;
    private MyInternalFrame frame ;
    
    
    // Default constructor
    public View( Model model )
    {
    	desktop = new JDesktopPane(); 
    	desktop.setDragMode( JDesktopPane.OUTLINE_DRAG_MODE );
    	this.model = model;

        // Pass model to MapPanel
        mappingPanel = new MapPanel( model, 700,500 );
        
        // Create suburbs JComboBox
        suburbs = new JComboBox();
        
        // Set the layout managers on the containers
        contentPane.setLayout( new BorderLayout() );
        panningPanel.setLayout( new BorderLayout() );
        innerPanel.setLayout( new BorderLayout() );
        zoomingPanel.setLayout( new GridLayout( 3, 1 ) );
        buttonsPanel.setLayout( new BorderLayout() );
        statusPanel.setLayout( new BoxLayout( statusPanel, BoxLayout.X_AXIS ) );
        
        // Set container properties
        statusPanel.setBorder( new BevelBorder( BevelBorder.LOWERED) );
        statusLabel.setHorizontalAlignment( SwingConstants.LEFT );
        statusPanel.setPreferredSize( new Dimension( this.getWidth(), 16) );
        
        // Add widgets to containers
        statusPanel.add( statusLabel );
        panningPanel.add( upPanning, BorderLayout.NORTH );
        panningPanel.add( rightPanning, BorderLayout.EAST );
        panningPanel.add( downPanning, BorderLayout.SOUTH );
        panningPanel.add( leftPanning, BorderLayout.WEST );
        zoomingPanel.add( zoomInButton );
        zoomingPanel.add( zoomOutButton );
        zoomingPanel.add( resetButton );
        innerPanel.add( panningPanel, BorderLayout.SOUTH );
        buttonsPanel.add( innerPanel, BorderLayout.CENTER );
        buttonsPanel.add(suburbs,BorderLayout.NORTH);
        buttonsPanel.add( zoomingPanel, BorderLayout.SOUTH );
        contentPane.add( buttonsPanel, BorderLayout.EAST );
        contentPane.add( statusPanel, BorderLayout.SOUTH );
        
        // Add JDesktopPane and zoom map panel to JDesktopPane
        add( desktop );
        desktop.add( mappingPanel );
        
        /// Build the menu.
        JMenu fileMenu = new JMenu("File");
        JMenu editMenu = new JMenu("Edit");
        JMenu viewMenu = new JMenu("View");
        JMenu helpMenu = new JMenu("Help");
        
        // Construct menu
        menuBar.add( fileMenu );
        menuBar.add( editMenu );
        menuBar.add( viewMenu );
        menuBar.add( helpMenu );
        
        openAction = new JMenuItem("Open");   //, new ImageIcon("images/openfile.png")););
        saveAction = new JMenuItem("Save");   //, new ImageIcon("images/openfile.png")););
        exitAction = new JMenuItem("Exit");   //, new ImageIcon("images/exitfile.png")););
        cutAction = new JMenuItem("Cut");
        copyAction = new  JMenuItem("Copy");
        pasteAction = new JMenuItem("Paste");
        aboutAction = new JMenuItem("About");
        
        saveAsAction = new JMenu("Save as");
        railData = new JMenuItem("Rail Data");
        roadData = new JMenuItem("Road Data");
        regionData = new JMenuItem("Region Data");
        zoomPanelAction = new JMenuItem("Show Zoom Panel");
        labelsAction = new JCheckBoxMenuItem("Show Labels");
        labelsAction.setSelected(true);

        // Add actions to menu
        fileMenu.add( openAction );
        fileMenu.add( saveAction );
        fileMenu.add(saveAsAction);
        fileMenu.addSeparator();
        fileMenu.add( exitAction );
        editMenu.add( cutAction );
        editMenu.add( copyAction );
        editMenu.add( pasteAction );
        viewMenu.add( labelsAction );
        viewMenu.add( zoomPanelAction );
        helpMenu.add( aboutAction );
        setMenuVisibility(); 
        saveAsAction.add( regionData );
        saveAsAction.add( roadData );
        saveAsAction.add( railData );
        
        /// Set up window properties and make it appear
        setJMenuBar( menuBar );
        setDefaultCloseOperation( EXIT_ON_CLOSE );
        setSize( 800, 600 );
        setVisible( true );
        mappingPanel.setVisible( true );
        mappingPanel.setBounds( 0, 0, 800, 600 );
    }
    private void setMenuVisibility()
    {
    	 regionData.setEnabled(model.isRegionDataChanged());
         roadData.setEnabled(model.isRoadDataChanged());
         railData.setEnabled(model.isRailDataChanged());
        
    }
    public JDesktopPane getDesktop()
    {
    	return desktop;
    }
    
    /**
     *    Button event handlers
     *    @param    aL - ActionListener parameter set by Controller.
     */
    public void addButtonActionListeners( ActionListener aL )
    {
        resetButton.addActionListener( aL );
        zoomInButton.addActionListener( aL );
        zoomOutButton.addActionListener( aL );
        leftPanning.addActionListener( aL );
        rightPanning.addActionListener( aL );
        upPanning.addActionListener( aL );
        downPanning.addActionListener( aL );
        suburbs.addActionListener( aL );
    }
    
    /**
     *    Menu event handlers
     *    @param    aL - ActionListener parameter set by Controller.
     */
    public void addMenuActionListeners( ActionListener aL )
    {
        openAction.addActionListener( aL );
        saveAction.addActionListener( aL );
        exitAction.addActionListener( aL );
        cutAction.addActionListener( aL );
        copyAction.addActionListener( aL );
        pasteAction.addActionListener( aL );
        aboutAction.addActionListener( aL );
        labelsAction.addActionListener( aL );
        zoomPanelAction.addActionListener( aL );
        regionData.addActionListener(aL);
        roadData.addActionListener(aL);
        railData.addActionListener(aL);
    }
    
    /**
     *    Mouse motion event handlers
     *    @param    mmL - MouseMotionListener parameter set by Controller.
     */
    public void addMouseMotionListeners( MouseMotionListener mmL )
    {
        addMouseMotionListener( mmL );
    }
    
    /**
     *    Mouse event handlers
     *    @param    mmL - MouseListener parameter set by Controller.
     */
    public void addMouseListeners( MouseListener mL )
    {
        addMouseListener( mL );
    }
    
    /**
     *    Set status label
     *    @param    labelText - The text to display in the status bar.
     */
    public void setStatusLabel( String labelText )
    {
        statusLabel.setText( labelText );
    }
    
    /**
     *    Show File->Open dialog box
     *    @return    The filename selected.
     */
    public String showOpenFileDialog()
    {
        String fileSelected = null;
        JFileChooser chooser = new JFileChooser();
        
        chooser.addChoosableFileFilter(
            new FileFilter()
            {
                String description = "Scenario Files (*.scn)";
                String extension = "scn";
                
                public String getDescription()
                {
                    return description;
                }
                
                public boolean accept(File f)
                {
                    if( f == null ) return false;
                    if( f.isDirectory() ) return true;
                    return f.getName().toLowerCase().endsWith( extension );
                }
            }
        );
        
        int returnVal = chooser.showOpenDialog( this );
        if( returnVal == JFileChooser.APPROVE_OPTION )
            fileSelected = chooser.getSelectedFile().toString();
        
        return fileSelected;
    }
   
    public String showSaveAsFileDialog()
    {
        String fileSelected = null;
        JFileChooser chooser = new JFileChooser();
        
        int returnVal = chooser.showSaveDialog( this );
        if( returnVal == JFileChooser.APPROVE_OPTION )
            fileSelected = chooser.getSelectedFile().toString();
        
        return fileSelected;
    }
    
    //Create a new internal frame.
    public void createFrame() 
    {
    	try
    	{
    		System.out.println("internalframe");
            // TODO: Just read Victoria2.txt        
    		Model smallModel = new Model();
        	smallModel.readScenarioFile( model.getScenarioFileName() );
        	smallModel.setTranslation( 10.00, 10.00 );
            frame = new MyInternalFrame( smallModel );
            frame.setRect( mappingPanel.getRect() );
            frame.setVisible( true );                    //necessary as of 1.3
            desktop.add( frame );
            frame.setSelected( true );
    	
        }
        catch ( Exception e )
        {
            System.out.println( "ERR: " + e.toString() );
        }
        
    }
    
    /**
     *    Show Help->About dialog box
     */
    public void showAboutDialog()
    {
        JOptionPane.showMessageDialog(
            this,
            "MelbourneMap v1.2\n" + 
            "Created: 17/09/2012\n" +
            "(c) Alexis Wellavize (s/n: 6033482)\n" +
            "    Dotan Tamir (s/n: 6532969)" );
    }
    
    public MapPanel getMapPanel()
    {
        return mappingPanel;
    }
    
    /**
     *    Repaint both this JFrame and MapPanel JFrame
     */
    public void redraw()
    {
    	this.setMenuVisibility();
    	repaint();
        mappingPanel.redraw();
        
        if( frame != null )
        {
        	frame.setPath( model.getRectangle() );
        	frame.drawRect();
        }
    }

	public void setSuburbsComboBox( JComboBox suburbs )
    {
		this.suburbs = suburbs;
	}

	public JComboBox getSuburbsComboBox()
    {
		return suburbs;
	}
	
	public void populateJComoboBox()
	{
        ArrayList<String> list = new ArrayList<String>();
        
		for( Region r : model.getRegions().values() )
            list.add( r.getName() );
        
        // Sort suburb names
        Collections.sort( list );            
            
        for ( String s : list )
			suburbs.addItem( s );
        
		suburbs.setActionCommand( "chosen" );
	}
}
